package com.bwie.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bwie.mapper.*;
import com.bwie.pojo.*;
import com.bwie.service.AddOrderService;
import com.bwie.utils.FastFileUtil;
import com.bwie.utils.FreemarkerUtil;
import com.bwie.utils.R;
import com.bwie.vo.EsOrder;
import com.bwie.vo.MessageVo;
import com.rabbitmq.client.Channel;
import freemarker.template.TemplateException;
import io.jsonwebtoken.*;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @Title:
 * @BelongProjecet month0617
 * @BelongPackage com.bwie.service.impl
 * @Description:
 * @Copyright 研发一部
 * @Author: Mr.yan
 * @Date: 2024/6/17 13:07
 * @Version V1.0
 */
@Service
public class AddOrderServiceImpl implements AddOrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private EnquiryMapper enquiryMapper;
    @Autowired
    private DeliverMapper deliverMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private FastFileUtil fastFileUtil;

    @PostConstruct
    public void rabbitInit(){
        System.out.println("mq开始执行");

        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                System.out.println("消息发送失败重新发送");
                String s3 = message.toString();
                rabbitTemplate.convertSendAndReceive(s1,s2,s3);
            }
        });

        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                if (b){
                    System.out.println("消息发送成功");
                }else {
                    System.out.println("消息发送失败");
                }
            }
        });

    }

    @Override
    @Transactional
    public R addOrder(TbOrder tbOrder, String token) {
        try {
            //1.解析token，获取创建人的信息
            Claims claims = Jwts.parser().setSigningKey("bwie").parseClaimsJws(token).getBody();
            Integer userId = claims.get("id", Integer.class);
            TbUser tbUser = userMapper.selectOne(
                    new QueryWrapper<TbUser>().lambda().eq(TbUser::getId, userId)
            );
            tbOrder.setUserId(userId);
            tbOrder.setUserName(tbUser.getUserName());

            //2.生成订单编号
            String orderNum = "yjs"+ RandomUtil.randomNumbers(4);
            tbOrder.setOrderNum(orderNum);

            //3.创建时间
            tbOrder.setCreateTime(new Date());
            //4.添加
            for (TbGoods good : tbOrder.getGoods()) {
                //
                tbOrder.setGoodsId(good.getId());
                tbOrder.setGoodsNumber(good.getGoodsNumber());
                tbOrder.setGoodsDetails(good.getGoodsDetails());
                orderMapper.insert(tbOrder);

                //5.同步数据es
                TbEnquiry tbEnquiry = enquiryMapper.selectOne(
                        new QueryWrapper<TbEnquiry>().lambda().eq(TbEnquiry::getId, tbOrder.getEnquiryId())
                );
                tbOrder.setEnquiryName(tbEnquiry.getEnquiryName());
                TbDeliver tbDeliver = deliverMapper.selectOne(
                        new QueryWrapper<TbDeliver>().lambda().eq(TbDeliver::getId, tbOrder.getDeliverId())
                );
                tbOrder.setDeliverName(tbDeliver.getDeliverName());
                TbGoods tbGoods = goodsMapper.selectOne(
                        new QueryWrapper<TbGoods>().lambda().eq(TbGoods::getId, tbOrder.getGoodsId())
                );
                tbOrder.setGoodsName(tbGoods.getGoodsName());
                tbOrder.setGoodsNum(tbGoods.getGoodsNum());
                EsOrder esOrder = new EsOrder();
                BeanUtils.copyProperties(tbOrder,esOrder);
                esOrder.setOrderStatus(0);
                esOrder.setOrderSta("待审核");
                elasticsearchRestTemplate.save(esOrder);

                //生成静态页面
                HashMap<String, Object> map = new HashMap<>();
                map.put("esOrder",esOrder);
                FreemarkerUtil freemarkerUtil = new FreemarkerUtil();
                String utilHtml = freemarkerUtil.createHtml(map, "order", "C:\\freemaker\\" + UUID.randomUUID().toString() + ".html");String url = fastFileUtil.uploadFile(new File(utilHtml));
                tbOrder.setFreeHtml(url);
                orderMapper.updateById(tbOrder);

                // //通过mq生成静态页面
                // MessageVo messageVo = new MessageVo();
                // //生成唯一标识
                // String messageId = UUID.randomUUID().toString();
                // messageVo.setMessageId(messageId);
                // //将对象存入vo中
                // messageVo.setMessageBody(JSON.toJSONString(esOrder));
                // //将输入存ru缓存中，反正消费时重复消费
                // String message = JSON.toJSONString(messageVo);
                // String messageKey = "message:"+messageId;
                // stringRedisTemplate.opsForValue().set(messageKey,message);
                //
                // rabbitTemplate.convertSendAndReceive("directExchange","freeBind",message);

            }

            return R.success();
        } catch (Exception e) {
            return R.error(500,"采购数量只能是数字");
        }
    }

    @Override
    public R goodsList() {
        List<TbGoods> goods = goodsMapper.goodsList();
        return R.success(goods);
    }

    // @RabbitListener(queues = "freeMakerQueue")
    // public void freeMakerUrl (Message message, Channel channel){
    //     try {
    //         //1。接受发送过来的参数
    //         String s = message.toString();
    //         //2.判断是否消费
    //         MessageVo messageVo = JSON.parseObject(s, MessageVo.class);
    //         String messageKey = "message:"+messageVo.getMessageId();
    //         if (!stringRedisTemplate.hasKey(messageKey)){
    //             System.out.println("已经消费过了并不能重复消费");
    //             channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    //         }
    //
    //         //3.生成静态页面
    //         EsOrder esOrder = JSON.parseObject(messageVo.getMessageBody(), EsOrder.class);
    //         HashMap<String, Object> map = new HashMap<>();
    //         map.put("esOrder",esOrder);
    //         FreemarkerUtil freemarkerUtil = new FreemarkerUtil();
    //         String utilHtml = freemarkerUtil.createHtml(map, "order", "C:\\freemaker\\" + UUID.randomUUID().toString() + ".html");
    //         String url = fastFileUtil.uploadFile(new File(utilHtml));
    //         TbOrder tbOrder = orderMapper.selectOne(
    //                 new QueryWrapper<TbOrder>().lambda().eq(TbOrder::getId, esOrder.getId())
    //         );
    //         tbOrder.setFreeHtml(url);
    //         orderMapper.updateById(tbOrder);
    //
    //         //4.消费
    //         channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    //         //5.删除缓存防止重复消费
    //         stringRedisTemplate.delete(messageKey);
    //
    //         System.out.println("消费成功");
    //     } catch (Exception e) {
    //         throw new RuntimeException(e);
    //     }
    //
    // }
}
